package com.htsk.city.services.wechat.service;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.util.WxMaConfigHolder;
import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.aliyun.dysmsapi20170525.Client;
import com.aliyun.dysmsapi20170525.models.SendSmsRequest;
import com.aliyun.dysmsapi20170525.models.SendSmsResponse;
import com.htsk.city.services.core.dao.WxUserAddressDao;
import com.htsk.city.services.core.dao.WxUserDao;
import com.htsk.city.services.core.domain.WxUser;
import com.htsk.city.services.core.domain.WxUserAddress;
import com.htsk.city.services.core.entity.R;
import com.htsk.city.services.core.redis.RedisCache;
import com.htsk.city.services.wechat.params.UserLoginParam;
import com.htsk.city.services.wechat.params.UserRegisterParam;
import com.htsk.city.services.wechat.vo.UserInfoVO;
import com.htsk.city.services.wechat.vo.WxUserAddressVO;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Slf4j
@Service
public class UserService {

    @Resource
    private WxUserDao wxUserDao;

    @Resource
    private WxUserAddressDao wxUserAddressDao;
    @Resource
    private WxMaService wxMaService;

    @Resource
    private Client client;

    @Resource
    private RedisCache redisCache;
    /**
     * 通过账号密码登录
     * @param userLoginParam
     * @return
     */
    public R<String> login(UserLoginParam userLoginParam) {
        WxUser wxUser=wxUserDao.findByMobileOrEmail(userLoginParam.getAccount(),userLoginParam.getAccount());

        if (wxUser==null||!wxUser.getPassword().equals(userLoginParam.getPassword())){
            return R.fail("用户名/密码错误");
        }
        if (wxUser.getStatus()==0) {
            return R.fail("用户状态异常");
        }

        StpUtil.login(JSONUtil.toJsonStr(wxUser));

        return R.ok(StpUtil.getTokenValue());
    }

    /**
     * 获取用户信息
     * @param wxUser
     * @return
     */
    public R<UserInfoVO> getUserInfo(WxUser wxUser){
        return R.ok(new UserInfoVO(wxUser));
    }

    public UserInfoVO getUserInfo(Long userId){
        WxUser wxUser=wxUserDao.getById(userId);
        return new UserInfoVO(wxUser);
    }

    /**
     * 编辑用户信息
     * @param wxUser
     * @param userInfo
     * @return
     */
    public R<Boolean> saveUserInfo(WxUser wxUser,UserInfoVO userInfo){
        //WxUser user=wxUserDao.findById(wxUser.getOpenId());
        wxUser.setNickname(userInfo.getNickname());
        wxUser.setAvatar(userInfo.getAvatar());
        wxUser.setGender(userInfo.getGender());
        wxUser.setBirthday(userInfo.getBirthday());
        //user.setEmail(userInfo.getEmail());
        wxUser.setUpdateTime(DateUtil.date());
        wxUserDao.save(wxUser);
        return R.ok(true);
    }


    public R<Boolean> register(UserRegisterParam userRegisterParam){
        String code=redisCache.getCacheObject(userRegisterParam.getMobile()+"_sms_code");
        if (StrUtil.isEmpty(code)||!StrUtil.equals(code,userRegisterParam.getCode())){
            return R.fail("验证码无效");
        }
        if (userRegisterParam.getCityId() == null) {
            return R.fail("cityId为空");
        }

//        if (!userRegisterParam.getCode().equals("000999")){
//            return R.fail("验证码错误");
//        }
        if (StrUtil.isBlank(userRegisterParam.getWxCode())) {
            return R.fail("empty wx_code");
        }

        WxUser wxUser=wxUserDao.findByMobileOrEmail(userRegisterParam.getMobile(), "");
        if (wxUser!=null){
            return R.fail("手机号重复注册");
        }
        wxUser=userRegisterParam.getWxUser();
        try {
            WxMaJscode2SessionResult session = wxMaService.getUserService().getSessionInfo(userRegisterParam.getWxCode());
            wxUser.setOpenId(session.getOpenid());

            WxUser user=wxUserDao.findByOpenId(wxUser.getOpenId());
            if (user!=null){
                return R.fail("重复注册");
            }
        } catch (WxErrorException e) {
            return R.fail("获取OPENID失败");
        } finally {
            WxMaConfigHolder.remove();//清理ThreadLocal
        }
        wxUserDao.save(wxUser);
        return R.ok(true);
    }

    public R<Long> saveAddress(WxUser wxUser, WxUserAddressVO wxUserAddressVO){

        WxUserAddress wxUserAddress;
        if (wxUserAddressVO.getId()==null){
            wxUserAddress=new WxUserAddress();
            wxUserAddress.setWxUserId(wxUser.getId());
            wxUserAddress.setDelFlag(0);
            wxUserAddress.setCreateTime(DateUtil.date());
        }else {
            wxUserAddress=wxUserAddressDao.findById(wxUserAddressVO.getId()).orElse(null);
        }
        if (wxUserAddress == null) {
           return R.fail("地址不存在");
        }
        wxUserAddress.setUpdateTime(DateUtil.date());
        wxUserAddressVO.trans(wxUserAddress);
        if(wxUserAddressVO.getIsDefault()==1){
            List<WxUserAddress> wxUserAddressList=wxUserAddressDao.findByWxUserIdAndDelFlag(wxUser.getId(),0);
            for (WxUserAddress userAddress : wxUserAddressList) {
                userAddress.setIsDefault(0);
            }
            wxUserAddressDao.saveAll(wxUserAddressList);
        }
        wxUserAddressDao.save(wxUserAddress);

        return R.ok(wxUserAddress.getId());
    }

    public R<List<WxUserAddressVO>> listAddress(WxUser wxUser){
        List<WxUserAddress> wxUserAddressList=wxUserAddressDao.findByWxUserIdAndDelFlag(wxUser.getId(),0);
        return R.ok(wxUserAddressList.stream().map(WxUserAddressVO::new).collect(Collectors.toList()));
    }

    public R<Boolean> deleteAddress(WxUser wxUser,Long addressId){
        WxUserAddress wxUserAddress=wxUserAddressDao.findByIdAndWxUserId(addressId,wxUser.getId());
        if (wxUserAddress==null){
            return R.fail("地址不存在");
        }
        wxUserAddress.setDelFlag(1);
        wxUserAddressDao.save(wxUserAddress);
        return R.ok(true);
    }

    public R<Boolean> sendSms(String mobile) throws Exception {

        String code=redisCache.getCacheObject(mobile+"_sms_code");
        if (StrUtil.isNotEmpty(code)){
            return R.fail("不可频繁发送");
        }

        code= RandomUtil.randomNumbers(6);
        redisCache.setCacheObject(mobile+"_sms_code",code,3L, TimeUnit.MINUTES);
        SendSmsRequest sendSmsRequest = new SendSmsRequest()
                .setPhoneNumbers(mobile)
                .setSignName("贵州省珩图数字科技")
                .setTemplateCode("SMS_326855219")
                // TemplateParam为序列化后的JSON字符串。其中\"表示转义后的双引号。
                .setTemplateParam("{\"code\":\""+code+"\"}");

        // 发送 API 请求
        SendSmsResponse sendSmsResponse = client.sendSms(sendSmsRequest);
        log.info("【验证码】"+code+"【验证码发送结果】"+JSONUtil.toJsonStr(sendSmsResponse));
        if (sendSmsResponse.statusCode==200&&sendSmsResponse.body.code.equals("OK")){
            return R.ok(true);
        }
        return R.fail("发送失败");
    }
}
